home *** CD-ROM | disk | FTP | other *** search
/ The Original Shareware 1.1 / The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso / 6 / des_pc.zip / DES_PC.C
Text File  |  1985-12-01  |  23KB  |  717 lines

  1.  
  2. /* des: duplicate the NBS Data Encryption Standard in software.
  3.  * usage: des <file>
  4.  * prompts for the password
  5.  * If the filename ends in ".n" it will be decrypted with the key;
  6.  * otherwise it will be encrypted.
  7.  *
  8.  * Permutation algorithm:
  9.  *    The permutation is defined by its effect on each of the 16 nibbles
  10.  *    of the 64-bit input.  For each nibble we give an 8-byte bit array
  11.  *    that has the bits in the input nibble distributed correctly.  The
  12.  *    complete permutation involves ORing the 16 sets of 8 bytes designated
  13.  *    by the 16 input nibbles.  Uses 16*16*8 = 2K bytes of storage for
  14.  *    each 64-bit permutation.  32-bit permutations (P) and expansion (E)
  15.  *    are done similarly, but using bytes instead of nibbles.
  16.  *    Should be able to use long ints, adding the masks, at a
  17.  *    later pass.  Tradeoff: can speed 64-bit perms up at cost of slowing 
  18.  *    down expansion or contraction operations by using 8K tables here and
  19.  *    decreasing the size of the other tables.
  20.  * The compressions are pre-computed in 12-bit chunks, combining 2 of the
  21.  *    6->4 bit compressions.
  22.  * The key schedule is also precomputed.
  23.  * Compile with VALIDATE defined to run the NBS validation suite.
  24.  *
  25.  * Jim Gillogly, May 1977
  26.  * Modified 8/84 by Jim Gillogly and Lauren Weinstein to compile with
  27.  *   post-1977 C compilers and systems
  28.  *
  29.  * This program is now officially in the public domain, and is available for
  30.  * any non-profit use as long as the authorship line is retained.
  31.  */
  32.  
  33. /*#define VALIDATE    */    /* define to check the NBS validation suite */
  34. /*#define DEBUG     */
  35. /*#define LATTICE    */    /* define for Lattice C on IBM PC */
  36.  
  37. #include <stdio.h>
  38.  
  39. #ifndef LATTICE
  40. #include <sgtty.h>
  41. #include <signal.h>
  42. #include <sys/types.h>  /* for local timer */
  43. #include <sys/timeb.h>  /* ditto */
  44.  
  45. struct sgttyb ttybuf;            /* for gtty/stty         */
  46. int bye();                /* for caught interrupts     */
  47.  
  48. #endif
  49.  
  50. char iperm[16][16][8],fperm[16][16][8]; /* inital and final permutations*/
  51. char s[4][4096];            /* S1 thru S8 precomputed    */
  52. char p32[4][256][4];            /* for permuting 32-bit f output*/
  53. char kn[16][6];                /* key selections        */
  54.  
  55. endes(inblock,outblock)            /* encrypt 64-bit inblock    */
  56. char *inblock, *outblock;
  57. {    char iters[17][8];        /* workspace for each iteration */
  58.     char swap[8];            /* place to interchange L and R */
  59.     register int i;
  60.     register char *s, *t;
  61.  
  62.     permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  63.     for (i=0; i<16; i++)        /* 16 churning operations    */
  64.         iter(i,iters[i],iters[i+1]);
  65.                     /* don't re-copy to save space  */
  66.     s = swap; t = &iters[16][4];    /* interchange left        */
  67.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  68.     t = &iters[16][0];        /* and right            */
  69.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  70.     permute(swap,fperm,outblock);   /* apply final permutation    */
  71. }
  72.  
  73. dedes(inblock,outblock)            /* decrypt 64-bit inblock    */
  74. char *inblock,*outblock;
  75. {    char iters[17][8];        /* workspace for each iteration */
  76.     char swap[8];            /* place to interchange L and R */
  77.     register int i;
  78.     register char *s, *t;
  79.  
  80.     permute(inblock,iperm,iters[0]);/* apply initial permutation    */
  81.     for (i=0; i<16; i++)        /* 16 churning operations    */
  82.         iter(15-i,iters[i],iters[i+1]);
  83.                     /* reverse order from encrypting*/
  84.     s = swap; t = &iters[16][4];    /* interchange left        */
  85.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  86.     t = &iters[16][0];        /* and right            */
  87.     *s++ = *t++; *s++ = *t++; *s++ = *t++; *s++ = *t++;
  88.     permute(swap,fperm,outblock);   /* apply final permutation    */
  89. }
  90.  
  91. permute(inblock,perm,outblock)        /* permute inblock with perm    */
  92. char *inblock, *outblock;        /* result into outblock,64 bits */
  93. char perm[16][16][8];            /* 2K bytes defining perm.    */
  94. {    register int i,j;
  95.     register char *ib, *ob;        /* ptr to input or output block */
  96.     register char *p, *q;
  97.  
  98.     for (i=0, ob = outblock; i<8; i++)
  99.         *ob++ = 0;        /* clear output block        */
  100.     ib = inblock;
  101.     for (j = 0; j < 16; j += 2, ib++) /* for each input nibble    */
  102.     {    ob = outblock;
  103.         p = perm[j][(*ib >> 4) & 017];
  104.         q = perm[j + 1][*ib & 017];
  105.         for (i = 0; i < 8; i++)   /* and each output byte    */
  106.             *ob++ |= *p++ | *q++;   /* OR the masks together*/
  107.     }
  108. }
  109.  
  110. char ip[]                /* initial permutation P    */
  111. = {    58, 50, 42, 34, 26, 18, 10,  2,
  112.     60, 52, 44, 36, 28, 20, 12,  4,
  113.     62, 54, 46, 38, 30, 22, 14,  6,
  114.     64, 56, 48, 40, 32, 24, 16,  8,
  115.     57, 49, 41, 33, 25, 17,  9,  1,
  116.     59, 51, 43, 35, 27, 19, 11,  3,
  117.     61, 53, 45, 37, 29, 21, 13,  5,
  118.     63, 55, 47, 39, 31, 23, 15,  7    };
  119.  
  120. char fp[]                /* final permutation F      */
  121. = {    40,  8, 48, 16, 56, 24, 64, 32,
  122.     39,  7, 47, 15, 55, 23, 63, 31,
  123.     38,  6, 46, 14, 54, 22, 62, 30,
  124.     37,  5, 45, 13, 53, 21, 61, 29,
  125.     36,  4, 44, 12, 52, 20, 60, 28,
  126.     35,  3, 43, 11, 51, 19, 59, 27,
  127.     34,  2, 42, 10, 50, 18, 58, 26,
  128.     33,  1, 41,  9, 49, 17, 57, 25    };
  129.  
  130. /* expansion operation matrix   */    /* rwo: unused    */
  131. /* char ei[] = {    32,  1,  2,  3,  4,  5,
  132.      4,  5,  6,  7,  8,  9,
  133.      8,  9, 10, 11, 12, 13,
  134.     12, 13, 14, 15, 16, 17,
  135.     16, 17, 18, 19, 20, 21,
  136.     20, 21, 22, 23, 24, 25,
  137.     24, 25, 26, 27, 28, 29,
  138.     28, 29, 30, 31, 32,  1  };    */
  139.  
  140. char pc1[]                /* permuted choice table (key)  */
  141. = {    57, 49, 41, 33, 25, 17,  9,
  142.      1, 58, 50, 42, 34, 26, 18,
  143.     10,  2, 59, 51, 43, 35, 27,
  144.     19, 11,  3, 60, 52, 44, 36,
  145.  
  146.     63, 55, 47, 39, 31, 23, 15,
  147.      7, 62, 54, 46, 38, 30, 22,
  148.     14,  6, 61, 53, 45, 37, 29,
  149.     21, 13,  5, 28, 20, 12,  4    };
  150.  
  151. char totrot[]               /* number left rotations of pc1 */
  152. = {    1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28    };
  153.  
  154. char pc1m[56];              /* place to modify pc1 into    */
  155. char pcr[56];               /* place to rotate pc1 into    */
  156.  
  157. char pc2[]                /* permuted choice key (table)  */
  158. = {    14, 17, 11, 24,  1,  5,
  159.      3, 28, 15,  6, 21, 10,
  160.     23, 19, 12,  4, 26,  8,
  161.     16,  7, 27, 20, 13,  2,
  162.     41, 52, 31, 37, 47, 55,
  163.     30, 40, 51, 45, 33, 48,
  164.     44, 49, 39, 56, 34, 53,
  165.     46, 42, 50, 36, 29, 32    };
  166.  
  167. char si[8][64]              /* 48->32 bit compression tables*/
  168. = {                    /* S[1]             */
  169.     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  170.      0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  171.      4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  172.     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  173.                     /* S[2]             */
  174.     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  175.      3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  176.      0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  177.     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
  178.                     /* S[3]             */
  179.     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  180.     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  181.     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  182.      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  183.                     /* S[4]             */
  184.      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  185.     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  186.     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  187.      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  188.                     /* S[5]             */
  189.      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  190.     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  191.      4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  192.     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  193.                     /* S[6]             */
  194.     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  195.     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  196.      9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  197.      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  198.                     /* S[7]             */
  199.      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  200.     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  201.      1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  202.      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  203.                     /* S[8]             */
  204.     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  205.      1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  206.      7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  207.      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11    };
  208.  
  209. char p32i[]                /* 32-bit permutation function  */
  210. = {    16,  7, 20, 21,
  211.     29, 12, 28, 17,
  212.      1, 15, 23, 26,
  213.      5, 18, 31, 10,
  214.      2,  8, 24, 14,
  215.     32, 27,  3,  9,
  216.     19, 13, 30,  6,
  217.     22, 11,  4, 25    };
  218.  
  219. desinit(key)                /* initialize all des arrays    */
  220. char *key;
  221. {
  222. #ifdef DEBUG
  223. /*deb*/ printf("Initial perm init.\n");
  224. #endif
  225.     perminit(iperm,ip);        /* initial permutation        */
  226. #ifdef DEBUG
  227. /*deb*/ printf("Final perm init.\n");
  228. #endif
  229.     perminit(fperm,fp);        /* final permutation        */
  230. #ifdef DEBUG
  231. /*deb*/ printf("Key sched init.\n");
  232. #endif
  233.     kinit(key);            /* key schedule            */
  234. #ifdef DEBUG
  235. /*deb*/ printf("Compression init.\n");
  236. #endif
  237.     sinit();            /* compression functions    */
  238.  
  239. #ifdef DEBUG
  240. /*deb*/ printf("32-bit perm init.\n");
  241. #endif
  242.     p32init();            /* 32-bit permutation in f    */
  243. #ifdef DEBUG
  244. /*deb*/ printf("End init.\n");
  245. #endif
  246. }
  247.  
  248. int bytebit[]               /* bit 0 is left-most in byte    */
  249.     = {    0200,0100,040,020,010,04,02,01 };
  250.  
  251. int nibblebit[] = { 010,04,02,01 };
  252.  
  253. sinit()                 /* initialize s1-s8 arrays        */
  254. {    register int i,j;
  255.  
  256.     for (i=0; i<4; i++)        /* each 12-bit position        */
  257.         for (j=0; j<4096; j++)  /* each possible 12-bit value   */
  258.             s[i][j]=(getcomp(i*2,j>>6)<<4) |
  259.                 (017&getcomp(i*2+1,j&077));
  260.                     /* store 2 compressions per char*/
  261. }
  262.  
  263. getcomp(k,v)                /* 1 compression value for sinit*/
  264. int k,v;
  265. {    register int i,j;        /* correspond to i and j in FIPS*/
  266.  
  267.     i=((v&040)>>4)|(v&1);        /* first and last bits make row */
  268.     j=(v&037)>>1;            /* middle 4 bits are column    */
  269.     return (int) si[k][(i<<4)+j];   /* result is ith row, jth col   */
  270. }
  271.  
  272. kinit(key)                /* initialize key schedule array*/
  273. char *key;                /* 64 bits (will use only 56)   */
  274. {    register int i,j,l;
  275.     int m;
  276.  
  277.     for (j=0; j<56; j++)        /* convert pc1 to bits of key   */
  278.     {    l=pc1[j]-1;        /* integer bit location        */
  279.         m = l & 07;        /* find bit            */
  280.         pc1m[j]=(key[l>>3] &    /* find which key byte l is in  */
  281.             bytebit[m])    /* and which bit of that byte   */
  282.             ? 1 : 0;    /* and store 1-bit result    */
  283.     }
  284.     for (i=0; i<16; i++)        /* for each key sched section   */
  285.         for (j=0; j<6; j++)    /* and each byte of the kn    */
  286.             kn[i][j]=0;    /* clear it for accumulation    */
  287.     for (i=0; i<16; i++)        /* key chunk for each iteration */
  288.     {    for (j=0; j<56; j++)    /* rotate pc1 the right amount  */
  289.         pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28];
  290.             /* rotate left and right halves independently   */
  291.         for (j=0; j<48; j++)    /* select bits individually    */
  292.         if (pcr[pc2[j]-1])    /* check bit that goes to kn[j] */
  293.             {    l= j & 07;
  294.                 kn[i][j>>3] |= bytebit[l];
  295.             }        /* mask it in if it's there    */
  296.     }
  297. }
  298.  
  299. p32init()                /* initialize 32-bit permutation*/
  300. {    register int l, j, k;
  301.     int i,m;
  302.  
  303.     for (i=0; i<4; i++)        /* each input byte position    */
  304.         for (j=0; j<256; j++)    /* all possible input bytes    */
  305.         for (k=0; k<4; k++)    /* each byte of the mask    */
  306.             p32[i][j][k]=0;    /* clear permutation array    */
  307.     for (i=0; i<4; i++)        /* each input byte position    */
  308.         for (j=0; j<256; j++)    /* each possible input byte    */
  309.         for (k=0; k<32; k++)    /* each output bit position    */
  310.         {   l=p32i[k]-1;    /* invert this bit (0-31)    */
  311.             if ((l>>3)!=i)    /* does it come from input posn?*/
  312.             continue;    /* if not, bit k is 0        */
  313.             if (!(j&bytebit[l&07]))
  314.             continue;    /* any such bit in input?    */
  315.             m = k & 07;     /* which bit is it?        */
  316.             p32[i][j][k>>3] |= bytebit[m];
  317.         }
  318. }
  319.  
  320. perminit(perm,p)            /* initialize a perm array    */
  321. char perm[16][16][8];            /* 64-bit, either init or final */
  322. char p[64];
  323. {    register int l, j, k;
  324.     int i,m;
  325.  
  326.     for (i=0; i<16; i++)        /* each input nibble position   */
  327.         for (j=0; j<16; j++)    /* all possible input nibbles   */
  328.         for (k=0; k<8; k++)    /* each byte of the mask    */
  329.             perm[i][j][k]=0;/* clear permutation array    */
  330.     for (i=0; i<16; i++)        /* each input nibble position   */
  331.         for (j = 0; j < 16; j++)/* each possible input nibble   */
  332.         for (k = 0; k < 64; k++)/* each output bit position    */
  333.         {   l = p[k] - 1;    /* where does this bit come from*/
  334.             if ((l >> 2) != i)  /* does it come from input posn?*/
  335.             continue;    /* if not, bit k is 0        */
  336.             if (!(j & nibblebit[l & 3]))
  337.             continue;    /* any such bit in input?    */
  338.             m = k & 07;    /* which bit is this in the byte*/
  339.             perm[i][j][k>>3] |= bytebit[m];
  340.         }
  341. }
  342.  
  343. iter(num,inblock,outblock)        /* 1 churning operation        */
  344. int num;                /* i.e. the num-th one        */
  345. char *inblock, *outblock;        /* 64 bits each            */
  346. {    char fret[4];            /* return from f(R[i-1],key)    */
  347.     register char *ib, *ob, *fb;
  348. /*    register int i;    */    /* rwo: unused    */
  349.  
  350.     ob = outblock; ib = &inblock[4];
  351.     f(ib, num, fret);        /* the primary transformation   */
  352.     *ob++ = *ib++;            /* L[i] = R[i-1]        */
  353.     *ob++ = *ib++;
  354.     *ob++ = *ib++;
  355.     *ob++ = *ib++;
  356.     ib = inblock; fb = fret;    /* R[i]=L[i] XOR f(R[i-1],key)  */
  357.     *ob++ = *ib++ ^ *fb++;
  358.     *ob++ = *ib++ ^ *fb++;
  359.     *ob++ = *ib++ ^ *fb++;
  360.     *ob++ = *ib++ ^ *fb++;
  361. }
  362.  
  363. f(right,num,fret)            /* critical cryptographic trans */
  364. char *right, *fret;            /* 32 bits each            */
  365. int num;                /* index number of this iter    */
  366. {    register char *kb, *rb, *bb;    /* ptr to key selection &c    */
  367.     char bigright[6];        /* right expanded to 48 bits    */
  368.     char result[6];            /* expand(R) XOR keyselect[num] */
  369.     char preout[4];            /* result of 32-bit permutation */
  370.  
  371.     kb = kn[num];            /* fast version of iteration    */
  372.     bb = bigright;
  373.     rb = result;
  374.     expand(right,bb);        /* expand to 48 bits        */
  375.     *rb++ = *bb++ ^ *kb++;        /* expanded R XOR chunk of key  */
  376.     *rb++ = *bb++ ^ *kb++;
  377.     *rb++ = *bb++ ^ *kb++;
  378.     *rb++ = *bb++ ^ *kb++;
  379.     *rb++ = *bb++ ^ *kb++;
  380.     *rb++ = *bb++ ^ *kb++;
  381.     contract(result,preout);    /* use S fns to get 32 bits    */
  382.     perm32(preout,fret);        /* and do final 32-bit perm    */
  383. }
  384.  
  385. perm32(inblock,outblock)        /* 32-bit permutation at end    */
  386. char *inblock,*outblock;        /* of the f crypto function    */
  387. {    register int j;
  388. /*    register int i;    */    /* rwo: unused    */
  389.     register char *ib, *ob;
  390.     register char *q;
  391.  
  392.     ob = outblock;            /* clear output block        */
  393.     *ob++ = 0; *ob++ = 0; *ob++ = 0; *ob++ = 0;
  394.     ib=inblock;            /* ptr to 1st byte of input    */
  395.     for (j=0; j<4; j++, ib++)    /* for each input byte        */
  396.     {    q = p32[j][*ib & 0377];
  397.         ob = outblock;        /* and each output byte        */
  398.         *ob++ |= *q++;        /* OR the 16 masks together    */
  399.         *ob++ |= *q++;
  400.         *ob++ |= *q++;
  401.         *ob++ |= *q++;
  402.     }
  403. }
  404.  
  405. expand(right,bigright)            /* 32 to 48 bits with E oper    */
  406. char *right,*bigright;            /* right is 32, bigright 48    */
  407. {
  408.     register char *bb, *r, r0, r1, r2, r3;
  409.  
  410.     bb = bigright;
  411.     r = right; r0 = *r++; r1 = *r++; r2 = *r++; r3 = *r++;
  412.     *bb++ = ((r3 & 0001) << 7) |    /* 32                */
  413.         ((r0 & 0370) >> 1) |    /* 1 2 3 4 5            */
  414.         ((r0 & 0030) >> 3);    /* 4 5                */
  415.     *bb++ = ((r0 & 0007) << 5) |    /* 6 7 8            */
  416.         ((r1 & 0200) >> 3) |    /* 9                */
  417.         ((r0 & 0001) << 3) |    /* 8                */
  418.         ((r1 & 0340) >> 5);    /* 9 10 11            */
  419.     *bb++ = ((r1 & 0030) << 3) |    /* 12 13            */
  420.         ((r1 & 0037) << 1) |    /* 12 13 14 15 16        */
  421.         ((r2 & 0200) >> 7);    /* 17                */
  422.     *bb++ = ((r1 & 0001) << 7) |    /* 16                */
  423.         ((r2 & 0370) >> 1) |    /* 17 18 19 20 21        */
  424.         ((r2 & 0030) >> 3);    /* 20 21            */
  425.     *bb++ = ((r2 & 0007) << 5) |    /* 22 23 24            */
  426.         ((r3 & 0200) >> 3) |    /* 25                */
  427.         ((r2 & 0001) << 3) |    /* 24                */
  428.         ((r3 & 0340) >> 5);    /* 25 26 27            */
  429.     *bb++ = ((r3 & 0030) << 3) |    /* 28 29            */
  430.         ((r3 & 0037) << 1) |    /* 28 29 30 31 32        */
  431.         ((r0 & 0200) >> 7);    /* 1                */
  432. }
  433.  
  434. contract(in48,out32)            /* contract f from 48 to 32 bits*/
  435. char *in48,*out32;            /* using 12-bit pieces into bytes */
  436. {    register char *c;
  437.     register char *i;
  438.     register int i0, i1, i2, i3, i4, i5;
  439.  
  440.     i = in48;
  441.     i0 = *i++; i1 = *i++; i2 = *i++; i3 = *i++; i4 = *i++; i5 = *i++;
  442.     c = out32;            /* do output a byte at a time   */
  443.     *c++ = s[0][07777 & ((i0 << 4) | ((i1 >> 4) & 017  ))];
  444.     *c++ = s[1][07777 & ((i1 << 8) | ( i2    & 0377 ))];
  445.     *c++ = s[2][07777 & ((i3 << 4) | ((i4 >> 4) & 017  ))];
  446.     *c++ = s[3][07777 & ((i4 << 8) | ( i5    & 0377 ))];
  447. }
  448.  
  449. /* End of DES algorithm (except for calling desinit below)    */
  450.  
  451. #ifndef VALIDATE
  452. char *inname, *outname;
  453. FILE *infile, *outfile;
  454.  
  455. int encrypting;
  456. char buf[512];
  457. char keyx[9], keyy[9];
  458.  
  459. char *malloc(), *strcpy(), *strcat();
  460.  
  461. main(argc, argv)
  462. int argc; char *argv[];
  463. {    register char *u;
  464.     char *filename;
  465.  
  466.     if (argc < 2)            /* filenames given? */
  467.     {  fprintf(stderr, "Usage: des file ...\n");
  468.        exit(1);     
  469.     }
  470.  
  471.     for (++argv; --argc; ++argv)
  472.     {    inname = *argv;
  473.         outname = filename = malloc((unsigned) strlen(inname) + 3);
  474.         strcpy(filename, inname);
  475.         u = &filename[strlen(filename) - 2]; /* check last 2 chars */
  476.  
  477.         encrypting = (strcmp(".n", u) != 0);
  478.         if (!encrypting) *u = 0; /* strip .n from output filename */
  479.         else strcat(filename, ".n");  /* or add .n to output file */
  480.  
  481.         if ((infile = fopen(inname, "rb")) == NULL)
  482.         {    fprintf(stderr,"Can't read %s.\n", inname);
  483.             exit(1);
  484.         }
  485.         if ((outfile = fopen(outname, "rb")) != NULL)
  486.         {    fprintf(stderr, "%s would be overwritten.\n",outname);
  487.             exit(1);
  488.         }
  489.         if ((outfile = fopen(outname, "wb")) == NULL)
  490.         {    fprintf(stderr,"Can't write %s.\n", outname);
  491.             exit(1);
  492.         }
  493.  
  494.         key_get("Type password for ");
  495.         for (;;)
  496.         {    strcpy(keyx, keyy);
  497.             key_get("Verify password for ");
  498.             if (strcmp(keyx, keyy) == 0) break;
  499.         }
  500.         desinit(keyx);      /* set up tables for DES    */
  501.  
  502.         if (pfile() == 0) unlink(inname);
  503.         else    fprintf(stderr,
  504.                "%s: I/O Error -- File unchanged\n", inname);
  505.  
  506.         fclose(outfile);
  507.         fclose(infile);
  508.     }
  509.     exit(0);
  510. }
  511.  
  512. key_get(mes)            /* get file key */
  513. char *mes;
  514. {    register int i, j;
  515.     char linebuf[256];
  516.     int count;
  517.  
  518.     for (i=0; i<14; i++) keyy[i]=0;
  519.  
  520. #ifdef LATTICE
  521. #else
  522.     gtty(0, &ttybuf);
  523.     ttybuf.sg_flags &= ~ECHO;  /* turn off echoing */
  524.     signal(SIGINT, bye);    /* catch ints */
  525.     stty(0, &ttybuf);
  526. #endif
  527.  
  528.     printf("%s%s: ", mes, inname);
  529.     fflush(stdout);
  530.  
  531.     count = read(0, linebuf, 256);  /* read input line */
  532.     printf("\n");
  533.  
  534. #ifndef LATTICE
  535.     ttybuf.sg_flags |= ECHO;      /* restore echo */
  536.     stty(0, &ttybuf);
  537. #endif
  538.  
  539.     linebuf[count] = 0;  /* null terminate */
  540.     if (linebuf[count-1] == '\n')  /* ignore any terminating newline */
  541.     {  linebuf[count-1] = 0;
  542.        count--;     
  543.     }
  544.     if (count > 8) count = 8;    /* only use 8 chars */
  545.     for (i = j = 0; count--;)
  546.        keyy[i++] = linebuf[j++];
  547. }
  548.  
  549. pfile()                 /* process the file        */
  550. {    register int m, nsave;
  551.     register char *b;
  552.     int j;
  553.  
  554.     while (m = fread(buf, 1, 512, infile))
  555.     {
  556.         if ((nsave = m) < 0)    /* read error            */
  557.         return(-1);
  558.         for (b=buf; m>0;    /* encrypt/decrypt 1 buffer-full*/
  559.         m -= 8, b += 8)        /* 8-byte blocks        */
  560.         {   if (encrypting)
  561.         {   if (m<8)        /* don't have a full 64 bits    */
  562.             {   for (j=0; j<8-m; j++)
  563.                 b[m+j]=garbage(); /* fill block with trash  */
  564.             nsave += 8-m;   /* complete the block        */
  565.             }
  566.             else j=0    /* number of nulls in last block*/
  567.             endes(b,b);    /* don't need diff input, output*/
  568.         }
  569.         else            /* decrypting            */
  570.         {   if (m < 8) deout(b, 1); /* last byte in file: count */
  571.             else
  572.             {   dedes(b, b); /* decrypt and output block    */
  573.             deout(b, 0);
  574.             }
  575.         }
  576.         }
  577.         if (encrypting) if (fwrite(buf, 1, nsave, outfile) != nsave)
  578.             return(-1);
  579.     }
  580.     /* have now encrypted/decrypted the whole file;
  581.      * need to append the byte count for the last block if encrypting.
  582.      */
  583.     if (encrypting) fputc(8 - j, outfile);  /* how many good bytes? */
  584.     return(0);
  585. }
  586.  
  587. int outcount = 0;            /* see when caught up with delay*/
  588.  
  589. deout(block,flag)            /* 1-block delay on output    */
  590. char *block,flag;            /* 64-bit block, last block flag*/
  591. {    static char last[8];        /* previous input block        */
  592.     register int i;
  593. /*    register char *c,*j;    */    /* rwo: unused    */
  594.  
  595.     if (flag)            /* output the last few bytes    */
  596.     {
  597.         fwrite(last, 1, block[0] & 0377, outfile);
  598.         return;
  599.     }
  600.     if (outcount++)            /* seen any blocks before?    */
  601.         fwrite(last, 1, 8, outfile);
  602.     for (i = 0; i < 8; i++) last[i] = block[i]; /* copy the block   */
  603. }
  604.  
  605. garbage()                /* generate garbage for filling */
  606. /* This garbage should be as random as possible.  We're using subsequent calls
  607.  * on the timer, but ideally each byte should be uncorrelated.  Preferable
  608.  * would be to call the timer once and use it to initialize a dumb random
  609.  * number generator.
  610.  */
  611. {
  612. #ifdef LATTICE
  613.     long timer(), ltime;
  614.  
  615.     ltime = timer();
  616.     return (int) ltime & 0377;
  617. #else
  618.     struct timeb tp;
  619.  
  620.     ftime(&tp);            /* get current time        */
  621.     return tp.millitm;        /* return time in milliseconds  */
  622. #endif
  623. }
  624.  
  625. #ifndef LATTICE
  626.  
  627. /* restore echo to tty and exit */
  628. bye()
  629. {
  630.     ttybuf.sg_flags |= ECHO;  /* restore echoing */
  631.     stty(0, &ttybuf);
  632.     exit(2);
  633. }
  634.  
  635. #endif
  636.  
  637. #else       /* validation */
  638.  
  639. #define VALFILE "valid.triples"
  640.  
  641. FILE *fd;
  642.  
  643. char key[8], plain[8], cipher[8], processed[8];
  644.  
  645. main()  /* read key/plain/cipher triples until exhausted */
  646. {    int count, i;
  647.  
  648.     if ((fd = fopen(VALFILE, "r")) == NULL)
  649.     {    fprintf(stderr, "Can't read %s.\n", VALFILE);
  650.         exit(1);
  651.     }
  652.     count = 0;
  653.     desinit(key);        /* initialize most of the arrays */
  654.     while (readvals())
  655.     {    kinit(key);    /* initialize key stuff        */
  656.         printf("Key: "); writehex(key);
  657.         printf("  Plain: "); writehex(plain);
  658.         printf("  Cipher: "); writehex(cipher);
  659.         printf("\n");
  660.         endes(plain, processed); /* encipher the plaintext */
  661.         printf("Encry:  "); writehex(processed);
  662.         printf("\n");
  663.         for (i = 0; i < 8; i++)
  664.             if (processed[i] != cipher[i])
  665.                 printf("Encryption failed.\n");
  666.         dedes(cipher, processed); /* decipher the ciphertext */
  667.         printf("Decry:  "); writehex(processed);
  668.         printf("\n");
  669.         for (i = 0; i < 8; i++)
  670.             if (processed[i] != plain[i])
  671.                 printf("Decryption failed.\n");
  672.         count++;
  673.     }
  674.     printf("Processed %d tests.\n", count);
  675. }
  676.  
  677. readvals()    /* get the next legit triple */
  678. {    int r;
  679.  
  680.     r = readhex(key);
  681.     readhex(plain);
  682.     readhex(cipher);
  683.     return r;
  684. }
  685.  
  686. writehex(str)   /* write the 64-bit hex string */
  687. char *str;
  688. {    int i;
  689.  
  690.     for (i = 0; i < 8; i++)
  691.         printf("%02x", str[i] & 0377);
  692. }
  693.  
  694. hex(n)  /* convert hex nibble into integer */
  695. int n;
  696. {
  697.     if (n >= 'A' && n <= 'F') return n - 'A' + 10;
  698.     return n - '0';
  699. }
  700.  
  701. readhex(str)    /* read 64 bits of hex code */
  702. char *str;
  703. {    int i, c;
  704.  
  705.     for (i = 0; i < 8; i++)
  706.     {    c = hex(getc(fd)) << 4;
  707.         str[i] = c | hex(getc(fd));
  708.     }
  709.     while ((c = getc(fd)) == ' ' || c == '\t' || c == '\n');
  710.     ungetc(c, fd);  /* skip to next field */
  711.     return c != EOF;
  712. }
  713.  
  714. #endif
  715.  
  716. /************ end scrydes ************/
  717.